package com.atdel.demo28;

/**
 * @BelongsProject: java_study
 * @BelongsPackage: com.atdel.demo28
 * @Author: Del
 * @CreateTime: 2025-03-26  16:10
 * @Description: 实现自定义 ArrayList 类
 *              支持动态扩容、基本增删改查操作。
 *              注意：本类不支持多线程操作。
 * @Version: 1.0
 */
public class MyArrayList<T> {

    // 默认初始化容量
    private static final int INITIAL_CAPACITY = 10;

    // 扩容倍数因子
    private static final double EXPANSION_FACTOR = 1.5;

    // 集合大小
    private int size;

    // 集合数据
    private Object[] elementData;

    /**
     * @author: Del
     * @date: 2025/3/26 16:22
     * @description:
     * 构造一个默认初始容量的空MyArrayList实例
     * 此构造函数初始化一个具有固定大小的Object数组，以存储列表元素，并将列表大小设置为0
     */
    public MyArrayList() {
        this.elementData = new Object[INITIAL_CAPACITY];
        this.size = 0;
    }


    /**
     * @author: Del
     * @date: 2025/3/26 16:22
     * @param capacity 指定的初始容量
     * @throws IllegalArgumentException 如果初始容量小于0
     * @description:
     * 构造一个具有指定初始容量的空MyArrayList实例
     * 此构造函数允许用户指定列表的初始容量，以适应不同的数据存储需求
     * 如果指定的容量小于0，则抛出IllegalArgumentException异常
     */
    public MyArrayList(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("初始容量不能为负数");
        }
        this.elementData = new Object[capacity];
        this.size = 0;
    }

     /**
      * @author: Del
      * @date: 2025/3/26 16:21
      * @param t 要添加的元素
      * @return void
      * @description: 添加元素到集合末尾
      */
    public void add(T t) {
        // 检查当前数组是否已满，如果已满，则需要扩容
        if (size == elementData.length) {
            // 计算新的数组容量，这里乘以预设的扩展因子EXPANSION_FACTOR
            int newCapacity = (int) (elementData.length * EXPANSION_FACTOR);
            // 创建一个新的数组，容量为计算出的新容量
            Object[] newElementData = new Object[newCapacity];
            // 将原数组中的元素复制到新数组中
            System.arraycopy(elementData, 0, newElementData, 0, elementData.length);
            // 使原数组引用指向新数组，释放旧数组
            elementData = newElementData;
        }
        // 向数组中添加新元素，并增加size计数
        elementData[size++] = t;
    }

    /**
     * @author: Del
     * @date: 2025/3/26 16:18
     * @param index 要删除的元素索引
     * @return void
     * @description: 根据索引删除元素
     */
    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界");
        }
        for (int i = index; i < size - 1; i++) {
            elementData[i] = elementData[i + 1];
        }
        // 清除最后一个元素引用，防止内存泄漏
        elementData[size - 1] = null;
        size--;
    }



    /**
     * @author: Del
     * @date: 2025/3/26 16:18
     * @param index 索引
     * @param t 新值
     * @return void
     * @description:  修改指定索引位置的元素
     */
    public void set(int index, T t) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界");
        }
        elementData[index] = t;
    }



    /**
     * @author: Del
     * @date: 2025/3/26 16:18
     * @param index 索引
     * @return T 指定索引位置的元素
     * @description: 获取指定索引位置的元素
     */
    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界");
        }
        return (T) elementData[index];
    }

    /**
     * @author: Del
     * @date: 2025/3/26 16:19
     * @return int 集合大小
     * @description:  获取集合大小
     */
    public int size() {
        return size;
    }



    /**
     * @author: Del
     * @date: 2025/3/26 16:19
     * @return boolean 是否为空
     * @description:  判断集合是否为空
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * @author: Del
     * @date: 2025/3/26 16:19
     * @return void
     * @description: 清空集合
     */
    public void clear() {
        for (int i = 0; i < size; i++) {
            elementData[i] = null; // 清除所有引用，防止内存泄漏
        }
        size = 0;
    }

    /**
     * @author: Del
     * @date: 2025/3/26 16:19
     * @param t 要查找的元素
     * @return boolean 是否包含
     * @description:  判断集合是否包含某个元素
     */
    public boolean contains(T t) {
        if (t == null) {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null) {
                    return true;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (t.equals(elementData[i])) {
                    return true;
                }
            }
        }
        return false;
    }


    /**
     * @author: Del
     * @date: 2025/3/26 16:20
     * @param t 要查找的元素
     * @return int 索引，若不存在则返回 -1
     * @description: 获取某个元素首次出现的索引
     */
    public int indexOf(T t) {
        if (t == null) {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null) {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (t.equals(elementData[i])) {
                    return i;
                }
            }
        }
        return -1;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(elementData[i]);
            if (i != size - 1) {
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}
